
package com.hlkj.pay.app.ad.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.math.BigDecimal;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.hlkj.pay.common.constants.MqConstant;
import com.hlkj.pay.config.ExtRocketMQTemplate;
import com.hlkj.pay.dto.ad.AdStatisticsDto;
import com.hlkj.pay.dto.common.OrderStatusDto;
import com.hlkj.pay.enums.AdEnum;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.infrastructure.model.ad.AdPayOrderDO;
import com.hlkj.pay.infrastructure.model.ad.AdRefundOrderDO;
import com.hlkj.pay.util.MerchantUtils;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/10/24 13:36
 */
@RequiredArgsConstructor
@Slf4j
@Component
public class AdPayOrderMessageHandler {

    private final ExtRocketMQTemplate extRocketMQTemplate;;

    @Value("${rocketmq.producer.ad_order_delay_level:5}")
    private Integer orderDelayLevel;
    @Value("${rocketmq.consumer.ad_order_delay_consumer_max_count:11}")
    private Integer adOrderDelayConsumerMaxCount;

    /**
     * 提交订单
     * 
     * @param adPayOrderDO
     */
    void submitOrder(AdPayOrderDO adPayOrderDO) {
        // 统计消息
        sendAdStatistics(adPayOrderDO.getAdId(), adPayOrderDO.getMchOrderNo(), adPayOrderDO.getAmount(), AdEnum.STATISTICS_TYPE.SUBMIT_ORDER, adPayOrderDO.getCreateTime());
        // 订单主动查询消息 10s 查询一次
        // 延迟消息支持的时间 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
        sendAdOrderStatus(orderDelayLevel, adPayOrderDO.getMchOrderNo(), PayOrderEnums.ORDER_STATUS_TYPE.PAY_ORDER_STATUS);
        // 订单主动关闭 30min自动关闭
        // sendAdOrderStatus(orderCloseDelayLevel, adPayOrderDO.getMchOrderNo(),
        // PayOrderEnums.ORDER_STATUS_TYPE.ORDER_CLOSE);
    }

    /**
     *
     * @param adRefundOrderDO
     */
    void refundOrder(AdRefundOrderDO adRefundOrderDO) {
        // 统计消息
        sendAdStatistics(adRefundOrderDO.getAdId(), adRefundOrderDO.getRefundOrderNo(), adRefundOrderDO.getRefundAmount(), AdEnum.STATISTICS_TYPE.REFUND_ORDER,
                adRefundOrderDO.getCreateTime());
        // 退款订单主动查询消息10s 查询一次 退款等回调 不主动查询
        sendAdOrderStatus(orderDelayLevel, adRefundOrderDO.getRefundOrderNo(), PayOrderEnums.ORDER_STATUS_TYPE.REFUND_STATUS);
    };

    protected void sendAdStatistics(Long adId, String mchOrderNo, BigDecimal amount, AdEnum.STATISTICS_TYPE statisticsType, Long time) {
        AdStatisticsDto adStatisticsDto = new AdStatisticsDto();
        adStatisticsDto.setAdId(adId);
        adStatisticsDto.setOrderNo(mchOrderNo);
        if (amount != null) {
            adStatisticsDto.setAmount(MerchantUtils.bigDecimalToString(amount));
        }
        adStatisticsDto.setStatisticsType(statisticsType.getCode());
        if (time == null) {
            adStatisticsDto.setTime(System.currentTimeMillis());
        }
        else {
            adStatisticsDto.setTime(time);
        }
        adStatisticsDto.setSendTime(System.currentTimeMillis());
        try {
            extRocketMQTemplate.send(MqConstant.AD_STATISTICS_RECORD_TOPIC, adStatisticsDto);
        }
        catch (Exception e) {
            log.error("mq 发送异常:{}", e.getMessage(), e);
        }
    }

    void sendAdCall(Long adId) {
        AdStatisticsDto adStatisticsDto = new AdStatisticsDto();
        adStatisticsDto.setAdId(adId);
        adStatisticsDto.setOrderNo(UUID.randomUUID().toString());
        adStatisticsDto.setStatisticsType(AdEnum.STATISTICS_TYPE.CALL_ORDER.getCode());
        try {
            extRocketMQTemplate.send(MqConstant.AD_CALL_RECORD_TOPIC, adStatisticsDto);
        }
        catch (Exception e) {
            log.error("mq 发送异常:{}", e.getMessage(), e);
        }
    }

    void sendAdOrderStatus(Integer delay, String orderNo, PayOrderEnums.ORDER_STATUS_TYPE orderStatusType) {
        OrderStatusDto orderStatusDto = new OrderStatusDto();
        orderStatusDto.setOrderNo(orderNo);
        orderStatusDto.setOrderStatusType(orderStatusType.getCode());
        orderStatusDto.setDelayLevel(delay);
        orderStatusDto.setDelaySendTime(System.currentTimeMillis());
        orderStatusDto.setTotalConsumerCount(0);
        orderStatusDto.setDelayLevel(delay);
        try {
            // 延迟消息支持的时间 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
            extRocketMQTemplate.sendDelay(delay, MqConstant.AD_ORDER_STATUS_RECORD_TOPIC, orderStatusDto);
        }
        catch (Exception e) {
            log.error("mq 发送异常:{}", e.getMessage(), e);
        }
    }

    void sendAdOrderStatus(OrderStatusDto orderStatusDto) {
        Integer delay = orderStatusDto.getDelayLevel();
        if (delay == null) {
            delay = orderDelayLevel;
        }
        String orderNo = orderStatusDto.getOrderNo();
        if (delay > adOrderDelayConsumerMaxCount) {
            log.info("订单状态查询已超过30m等级,结束查询 order:{}", orderNo);
            return;
        }
        orderStatusDto.setDelaySendTime(System.currentTimeMillis());
        if (orderStatusDto.getTotalConsumerCount() == null) {
            orderStatusDto.setTotalConsumerCount(0);
        }
        orderStatusDto.setTotalConsumerCount(orderStatusDto.getTotalConsumerCount() + 1);
        // 当前时间没有查询到 到下一个等级
        delay = delay + 1;
        orderStatusDto.setDelayLevel(delay);
        try {
            // 延迟消息支持的时间 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
            extRocketMQTemplate.sendDelay(delay, MqConstant.AD_ORDER_STATUS_RECORD_TOPIC, orderStatusDto);
        }
        catch (Exception e) {
            log.error("mq 发送异常:{}", e.getMessage(), e);
        }
    }
}
